args = {
    "q": 'abc',
    "page": 1
}


class Length:
    def __init__(self, min, max):
        self.min = min
        self.max = max

    def validate(self, name, value):
        if len(value) >= self.min and len(value) <= self.max:
            return True
        else:
            raise ValueError('{}:字符过短或过长'.format(name))


class NumberRange:
    def __init__(self, min, max):
        self.min = min
        self.max = max

    def validate(self, name, value):
        if value >= self.min and value <= self.max:
            return True
        else:
            raise ValueError('{}:数字过大或过小'.format(name))


class StringField:
    type = 'field'

    def __init__(self, validators):
        self.validators = validators

    def validate(self, name, value):
        if isinstance(value, str) and len(value) > 0:
            for validator in self.validators:
                validator.validate(name, value)
            return True
        else:
            raise ValueError('{}: 请输入合法的字符'.format(name))


class IntField:
    type = 'field'

    def __init__(self, validators):
        self.validators = validators

    def validate(self, name, value):
        if isinstance(value, int):
            for validator in self.validators:
                validator.validate(name, value)
            return True
        else:
            raise ValueError('{}:请输入合法的数字'.format(name))


class SearchForm:
    q = StringField(validators=[Length(min=3, max=10)])
    page = IntField(validators=[NumberRange(min=1, max=99)])

    def __init__(self, data):
        self.data = data

    def validate(self):
        # 检验data的合法性
        # print(SearchForm.__dict__)
        print(dir(SearchForm))
        for name in dir(SearchForm):
            if not name.startswith('_'):
                field = getattr(SearchForm, name)
                if hasattr(field, 'type'):
                    print(name, field)
                    value = self.data.get(name)
                    if not field.validate(name, value):
                        return False
        return True

        # r1 = self.q.validate(self.data.get('q'))
        # r2 = self.page.validate(self.data.get('page'))
        # if r1 and r2:
        #     return True


if __name__ == '__main__':
    form = SearchForm(args)
    print(form.validate())
